#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>

using namespace std;

// 循环不变量
vector<vector<int>> generateMatrix(int n) {
    vector<vector<int>> result(n, vector<int>(n, 0));
    int loopCount = n / 2;  // 循环次数 每次循环处理顺时针一圈
    int startX = 0, startY = 0;  // 每一圈开始的索引 (0,0)(1,1)...
    int i, j;                    // 临时用的索引
    int count = 1;               // 要填充的值
    int middle = n / 2;  // n为奇数是 最后最中间位置需要再填上这个值
    int offset = 1;  // 每一圈后遍历完 遍历范围要缩小
    while (loopCount--) {
        i = startX;
        j = startY;

        // 每个for循环处理的数量都相同
        // 上边 从左往右遍历
        for (int j = startY; j < n - offset; j++) {
            result[startX][j] = count++;
        }
        // 右边 边从上往下遍历
        for (int i = startX; i < n - offset; i++) {
            result[i][n - offset] = count++;
        }
        // 下边 从右往左遍历
        for (int j = n - offset; j > startY; j--) {
            result[n - offset][j] = count++;
        }
        // 左边 从下往上遍历
        for (int i = n - offset; i > startX; i--) {
            result[i][startY] = count++;
        }

        // 下一圈起始位置索引都加一
        startX++;
        startY++;
        // 遍历的长度小一
        offset++;
    }

    if (n % 2 == 1) {
        result[middle][middle] = count;
    }

    return result;
}

/**
 *  初始化一个 n×n 大小的矩阵 mat，然后模拟整个向内环绕的填入过程：
    1.定义当前左右上下边界 l,r,t,b，初始值 num = 1，迭代终止值 tar = n * n；
    2.当 num <= tar 时，始终按照 从左到右 从上到下 从右到左 从下到上 填入顺序循环，每次填入后：
        a.执行 num += 1：得到下一个需要填入的数字；
        b.更新边界：例如从左到右填完后，上边界 t += 1，相当于上边界向内缩 1。
    3.使用num <= tar而不是l < r || t < b作为迭代条件，是为了解决当n为奇数时，矩阵中心数字无法在迭代过程中被填充的问题。
    4.最终返回 mat 即可。
 * 
 * @param n 
 * @return vector<vector<int>> 
 */
vector<vector<int>> generateMatrix2(int n) {
    int l = 0, r = n - 1, t = 0, b = n - 1;
    int num = 1, target = n * n;
    vector<vector<int>> result(n, vector<int>(n, 0));
    while (num <= target) {
        for (int i = l; i <= r; i++) {
            result[t][i] = num++;
        }
        t++;
        for (int i = t; i <= b; i++) {
            result[i][r] = num++;
        }
        r--;
        for (int i = r; i >= l; i--) {
            result[b][i] = num++;
        }
        b--;
        for (int i = b; i >= t; i--) {
            result[i][l] = num++;
        }
        l++;
    }

    return result;
}

int main() {
    int n;
    cout << "cin n: " << endl;
    cin >> n;
    vector<vector<int>> result = generateMatrix2(n);
    for (int i = 0, len1 = result.size(); i < len1; i++) {
        for (int j = 0, len2 = result[i].size(); j < len2; j++) {
            cout << result[i][j] << " ";
        }
        cout << endl;
    }

    system("pause");
    return 0;
}